.de EX
.nf
.ft CW
..
.de EE
.br
.fi
.ft
..
.TH SMLYACC 1
.SH NAME
smlyacc
\- the parser generator for SML#
.SH SYNOPSIS
.B smlyacc
[\fB-s\fP]
[\fB-p\fP\ \fIoutput_prefix\fP]
.I filename
.
.SH DESCRIPTION
.I SMLYacc
is a parser generator in the style of ML-Yacc.
It can accept grammer files of ML-Yacc, but generated programs
and their usage are not compatible to those of ML-Yacc.
Generated programs can be compiled by the SML# compiler.
.PP
By default, for an input file
.IR X.grm ,
.B smlyacc
generates
.I X.grm.sml
for the generated parser,
.I X.grm.sig
for the signature of tokens, and optionally
.I X.grm.desc
for the description of LALR parser construction.
To compile the generated program with SML#,
you need to write an inteface file
.I X.grm.smi
by yourself according to the generated signature
.I X.grm.sig.
.
.SS OPTIONS
.TP
\fB-s\fP
Insert the token signature at the beginning of the generated
.I .sml
file, instead of a separate
.I .sig
file.
.TP
\fB-p\fP\ \fIoutput_prefix\fP
Set the prefix of the output file names.
When
.I output_prefix
is set to
.IR X ,
.B smlyacc
generates
.IR X.sml ,
.IR X.sig ,
and
.IR X.desc .
The default is the same as the input file name.
.
.SH EXAMPLES
The following is a minimal example of an input file
.IR ex.grm :
.PP
.RS
.EX
%%
%term LPAREN | RPAREN | EOF
%nonterm start of word | exp of word
%pos int
%eop EOF
%name Example
%%
start : exp (exp)
exp : (0w0)
    | LPAREN exp RPAREN exp (exp1 + exp2)
.EE
.RE
.PP
By applying this file to
.BR smlyacc ,
.PP
.RS
.EX
smlyacc ex.grm
.EE
.RE
.PP
you obtain two files
.I ex.grm.sml
and
.IR ex.grm.sig .
Only
.I ex.grm.sml
needs to be compiled.
To compile it, you need to create the following
.I ex.grm.smi
file by yourself:
.PP
.RS
.EX
_require "basis.smi"
_require local "ml-yacc-lib.smi"
_require local "./ex.grm.sig"
structure ExampleLrVals =
struct
  structure Parser =
  struct
    type token (= boxed)
    type stream (= ref)
    type result = word
    type pos = int
    type arg = unit
    val makeStream : {lexer : unit -> token} -> stream
    val consStream : token * stream -> stream
    val getStream : stream -> token * stream
    val sameToken : token * token -> bool
    val parse : {lookahead : int,
                 stream : stream,
                 error : string * pos * pos -> unit,
                 arg : arg}
                -> result * stream
  end
  structure Tokens =
  struct
    type pos = Parser.pos
    type token = Parser.token
    val EOF: pos * pos -> token
    val RPAREN: pos * pos -> token
    val LPAREN: pos * pos -> token
  end
end
.EE
.RE
.PP
The types of token constructors (\f[CW]EOF\fP, \f[CW]RPAREN\fP, and
\f[CW]LPAREN\fP) are copied from the generated signature
.I ex.grm.sig
file by hand.
.PP
The \f[CW]parse\fP function in the generated program is the parser.
To invoke it, an imperative lexer function of type \f[CW]unit -> token\fP is
needed.
In the case of combining with SMLLex, the lexer is generated by SMLLex.
Suppose that SMLLex generates a lexer of the following interface:
.PP
.RS
.EX
structure ExampleLex =
struct
  exception LexError
  val makeLexer : (int -> string)
                  -> unit -> ExampleLrVals.Parser.token
end
.EE
.RE
.PP
A typical code joining SMLLex and SMLYacc looks like the following:
.PP
.RS
.EX
fun inputN n = TextIO.inputN (instream, n)
val lexer = ExampleLex.makeLexer inputN
val stream = ExampleLrVals.Parser.makeStream {lexer = lexer}
val (result, stream) =
    ExampleLrVals.parse
      {lookahead = 0, stream = stream,
       error = errorFn, arg = parserArg}
.EE
.RE
.
.SH HISTORY
SMLYacc is a derivative of ML-Yacc, which is originally developed by
David R. Tarditi and Andrew W. Appel.
When ML-Yacc was ported to SML#, the source code was restructured to
replace functor applications with SML#'s separate compilation and linking.
See the SML# document for major changes from the original ML-Yacc.
.
.SH SEE ALSO
.IR smllex (1)
.br
.IR "ML-Yacc User's Manual" ,
available at
https://www.smlnj.org/doc/ML-Yacc/
.br
.IR "SML# Document" ,
available at
https://www.pllab.riec.tohoku.ac.jp/smlsharp/docs/
